/**
 * Copyright 2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.edi.client.param;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Element;

import com.edi.Constant;
import com.edi.db.PreparedEql;
import com.edi.db.dao.EdiDAOException;
import com.edi.db.manager.DBManager;
import com.edi.db.table.RowEntity;
import com.edi.db.table.TableEntity;
import com.edi.exceptions.EdiParamException;

/**
 * 处理Table对象
 * 
 * @author 红木
 * 
 */
public class EdiTPOClientParam extends EdiClientParam {

	private static final Log log = LogFactory.getLog(EdiTPOClientParam.class);

	private final String METHOD_INSERT = "insert";
	private final String METHOD_UPDATE = "update";

	// private TableEntity table;
	private TableEntity removeTable; // 需删除记录实体
	private TableEntity addTable; // 需插入记录实体
	private TableEntity updateTable; // 需更新记录实体
	String tableName;

	public EdiTPOClientParam(Element ediPara) {
		super(ediPara);
		this.transaction = ediPara.elementText("transaction");
		tableName = ediPara.element("table").attributeValue("name");
		constructTable(ediPara.element("table"));
		if ("newRow".equalsIgnoreCase(this.methods))
			newTable();
	}

	/**
	 * 构造一个表结构返回前台
	 * 
	 */
	private void newTable() {

		DBManager dbManager = new DBManager(Constant.SERVER_APPNAME);
		String eql = "select * from " + tableName + " where 1<>1";
		PreparedEql preparedEql = new PreparedEql(eql);
		try {
			this.returnTable = dbManager.queryPreparedEql(preparedEql);
			RowEntity row = returnTable.newRow();
			returnTable.addRow(row);
			this.newRow = "1";
		} catch (EdiDAOException e) {
			e.printStackTrace();
			log.error(" 构造 TPO newTable 发生异常 " + e.getMessage());
		}
	}

	/**
	 * 解析客户端请求中的表内容，构造tableentity实例
	 * 
	 * @param tElement
	 */
	private void constructTable(Element tElement) {
		tableName = tElement.attributeValue("name");
		removeTable = new TableEntity(tableName);
		updateTable = new TableEntity(tableName);
		addTable = new TableEntity(tableName);

		Iterator<Element> rowIter = tElement.elementIterator("row");

		// 读取第一行，获得表的列信息
		Element rowDes = tElement.element("row");
		if (rowDes != null) {
			Iterator<Element> fieldIter = rowDes.elementIterator();
			while (fieldIter.hasNext()) {
				Element fieldE = fieldIter.next();
				String fieldName = fieldE.getName();
				if (StringUtils.isNotBlank(fieldName)) // 将fieldName
					// 都改成小写，与后面的提取统一，cya
					// 2009-3-9
					fieldName = fieldName.toLowerCase();
				String fieldType = fieldE.attributeValue("fieldType");
				boolean isPrimary = fieldE.attribute("primaryKey") == null ? false
						: true || fieldE.attribute("primaryKey").equals("1");
				removeTable.addField(fieldName, fieldType, isPrimary);
				updateTable.addField(fieldName, fieldType, isPrimary);
				addTable.addField(fieldName, fieldType, isPrimary);
			}
		}

		// 逐行读取，为表实例添加数据信息
		while (rowIter.hasNext()) {
			Element rowE = rowIter.next();
			Iterator<Element> cellIter = rowE.elementIterator();
			String operation = rowE.attributeValue("Operation");
			if (operation.equalsIgnoreCase("add")) {
				log.debug("add a row to addTable");
				constructTable(cellIter, addTable);
				// RowEntity row = addTable.newRow();
				// while (cellIter.hasNext()) {
				// Element cellE = cellIter.next();
				// row.addCell(cellE);
				// }
				// addTable.addRow(row);
				log.debug(" add addTable =" + addTable.toString());
			} else if (operation.equalsIgnoreCase("update")) {
				log.debug("add a row to udpateTable");
				constructTable(cellIter, updateTable);
				log.debug(" add updateTable =" + addTable.toString());
			} else if (operation.equalsIgnoreCase("remove")) {
				log.debug("add a row to removeTable");
				constructTable(cellIter, removeTable);
				log.debug(" add removeTable =" + removeTable.toString());
			}
		}
	}

	private void constructTable(Iterator<Element> cellIter, TableEntity entity) {
		RowEntity row = entity.newRow();
		while (cellIter.hasNext()) {
			Element cellE = cellIter.next();
			//增加 特殊变量 cya 2009-4-7
			String tempText = cellE.getText();
			//			log.debug(" before constructTable ="+cellE.asXML());
			//			log.debug("tempText ="+tempText);			
			cellE.clearContent();
			cellE.addCDATA(tempText);
			//			log.debug(" after constructTable ="+cellE.asXML());
			try {
				row.addCell(cellE);
			} catch (Exception e) {
				e.printStackTrace();
				log.error(e.getMessage());
			}
		}
		entity.addRow(row);
	}

	public void excuteClientParam() throws EdiParamException {
		DBManager dbManager = new DBManager(Constant.SERVER_APPNAME);
		// if (methods.equalsIgnoreCase(METHOD_INSERT)) {
		// if (dbManager.save(table)) {
		// state = Constant.EXEC_STATE_SUCESS;
		// } else {
		// state = Constant.EXEC_STATE_ERROR;
		// errorMessage.append("TPO occured error,save failed.");
		// }
		// } else {
		// if (dbManager.update(table)) {
		// state = Constant.EXEC_STATE_SUCESS;
		// } else {
		// state = Constant.EXEC_STATE_ERROR;
		// errorMessage.append("TPO occured error,save failed.");
		// }
		// }

		Map<String, TableEntity> tableMaps = generTableMaps();
		tableMaps.put("remove", this.removeTable);
		tableMaps.put("add", this.addTable);
		tableMaps.put("update", this.updateTable);
		try {
			dbManager.commitTables(tableMaps);
			state = Constant.EXEC_STATE_SUCESS;
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			state = Constant.EXEC_STATE_ERROR;
			errorMessage.append("TPO occured error,save failed.");
			errorMessage.append(e.getMessage());
		}
	}

	public Map<String, TableEntity> generTableMaps() {
		Map<String, TableEntity> tableMaps = new HashMap<String, TableEntity>();
		tableMaps.put("remove", this.removeTable);
		tableMaps.put("add", this.addTable);
		tableMaps.put("update", this.updateTable);
		return tableMaps;
	}

}
